/****************************************************************************
**
****************************************************************************/

#include <QSerialPort>
#include <QReadWriteLock>

#include "status/status.h"

#include "util.h"
#include "card/cardPuyue.h"
#include "card/cardZlg.h"
#include "cardMain.h"
#include "hciMain.h"
#include "chargeMain.h"

#include <QDebug>
#define CARDMAIN_DEBUG

static QReadWriteLock StartChargeServiceLock;
static QReadWriteLock StopChargeServiceLock;

//cmd flag
QList<bool> CardMain::start_charge_service_ = {false, false};
QList<bool> CardMain::stop_charge_service_ = {false, false};

QByteArray CardMain::card_number_;

CardMain::CardMain(QList<ChargeMain *> *chargelist, HciMain *hciMain, QObject *parent) : QThread(parent),
    m_quit(false),
    m_cycle(1000)
{
    hciMain_ = hciMain;
    chargeMainList_ = chargelist;

    abstractCard_ = new CardZlg(AbstractCard::KThaisenAndYunkuaichong);

    connect(this, &CardMain::SearchCard, abstractCard_, &AbstractCard::SearchCard);
    connect(abstractCard_, &AbstractCard::HandleCardNumber, this, &CardMain::HandleCardNumber);
}

CardMain::~CardMain()
{
    m_quit = true;
    wait();

    if (nullptr != abstractCard_) {
        delete abstractCard_;
        abstractCard_ = nullptr;
    }
}

bool CardMain::StartChargeService(quint8 gunno)
{
    bool res = false;

    StartChargeServiceLock.lockForRead();
    res = start_charge_service_.at(gunno);
    StartChargeServiceLock.unlock();

    return res;
}

void CardMain::SetStartChargeService(quint8 gunno)
{
    StartChargeServiceLock.lockForWrite();
    start_charge_service_.replace(gunno, true);
    StartChargeServiceLock.unlock();
}

void CardMain::ClearStartChargeService(quint8 gunno)
{
    StartChargeServiceLock.lockForWrite();
    start_charge_service_.replace(gunno, false);
    StartChargeServiceLock.unlock();
}

bool CardMain::StopChargeService(quint8 gunno)
{
    bool res = false;

    StopChargeServiceLock.lockForRead();
    res = stop_charge_service_.at(gunno);
    StopChargeServiceLock.unlock();

    return res;
}

void CardMain::SetStopChargeService(quint8 gunno)
{
    StopChargeServiceLock.lockForWrite();
    stop_charge_service_.replace(gunno, true);
    StopChargeServiceLock.unlock();
}

void CardMain::ClearStopChargeService(quint8 gunno)
{
    StopChargeServiceLock.lockForWrite();
    stop_charge_service_.replace(gunno, false);
    StopChargeServiceLock.unlock();
}

void CardMain::run()
{
    unsigned long timeout = 0;

    while (!m_quit) {
        if (10 > m_cycle) {
            m_cycle = 10;
        }

        if (!hciMain_->action_card()) {
            msleep(m_cycle);
            continue;
        }

        if (kGunNumberA != hciMain_->current_gun() && kGunNumberB != hciMain_->current_gun()) {
            msleep(m_cycle);
            continue;
        }

        switch (abstractCard_->card_state()) {
        case AbstractCard::KCardDown:
            abstractCard_->set_card_state(AbstractCard::kCardIdle); /* 对卡进行处理（比如：复位） */
            break;
        case AbstractCard::kCardIdle:
        case AbstractCard::kCardReady:
            timeout = 0;
            abstractCard_->set_card_state(AbstractCard::kCardActivation);
            current_gun_ = hciMain_->current_gun();
            emit SearchCard(); /* 寻卡 */
            break;
        case AbstractCard::kCardActivation:
            if (++timeout > 1000 / m_cycle) {
                timeout = 0;
                abstractCard_->set_card_state(AbstractCard::kCardIdle);
            }
            break;
        case AbstractCard::kCardFinish:
            break;
        case AbstractCard::KCardOffIdle:
            abstractCard_->set_card_state(AbstractCard::kCardIdle);
            break;
        case AbstractCard::KCardOffline:
            abstractCard_->set_card_state(AbstractCard::KCardDown); /* 数据异常 */
            break;
        default:
            break;
        }

        msleep(m_cycle);
    }
}

void CardMain::HandleCardNumber(QByteArray& card_number)
{
#ifdef CARDMAIN_DEBUG
    qDebug() << "[CardMain]-> card number:" << card_number.toHex(' ').toUpper();
#endif

    card_number_ = card_number;

    switch (chargeMainList_->at(current_gun_)->gun()->state()) {
    case Status::kReady:
        SetStartChargeService(current_gun_);
#ifdef CARDMAIN_DEBUG
        qDebug() << "[CardMain]-> start charge...";
#endif
        break;
    case Status::kCharging:
        SetStopChargeService(current_gun_);
#ifdef CARDMAIN_DEBUG
        qDebug() << "[CardMain]-> stop charge...";
#endif
        break;
    default:
        break;
    }

    abstractCard_->set_card_state(AbstractCard::KCardOffIdle); /* 进行离场处理 */
}
